import 'package:flutter/material.dart';

class ListViewPage extends StatefulWidget {
  @override
  _ListViewPageState createState() => _ListViewPageState();
}

class _ListViewPageState extends State<ListViewPage> {
  final title = "listview";

  var datas = <String>[];

  @override
  void initState() {
    super.initState();
    for (var i = 0; i < 30; i++) {
      datas.add(i.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    var listView = ListView.builder(
      itemBuilder: _buildItem,
      itemCount: datas.length,
    );
    return Scaffold(
      appBar: AppBar(title: Text(title)),
      body: listView,
    );
  }

  String currentData;
  StateSetter s;

  Widget _buildItem(BuildContext context, int index) {
    var width = MediaQuery.of(context).size.width;
    var text = datas[index];
    Widget w = LongPressDraggable<String>(
      data: text,
      child: ListTile(
        title: Text(text),
      ),
      feedback: StatefulBuilder(
        builder: (c, StateSetter s) {
          this.s = s;
          print("current Data = $currentData");
          return Material(
            child: Container(
              color: Colors.grey.withOpacity(0.4),
              width: width,
              child: ListTile(
                title: Text(currentData ?? ""),
              ),
            ),
          );
        },
      ),
      // feedbackOffset: Offset(0, 10),
      onDragStarted: () {
        print("onStart");
        this.currentData = text;
        s?.call(() {
          this.currentData = text;
        });
      },
      onDragEnd: (d) {
        this.s = null;
        print("onend");
      },
    );

    return DragTarget<String>(
      builder: (BuildContext context, List candidateData, List rejectedData) {
        return w;
      },
      onLeave: (s) {
        print("on leave");
      },
      onAccept: (s) {
        print("onaccept");
      },
      onWillAccept: (src) {
        print("onWillAccept");
        swap(src, text);
        return true;
      },
    );
  }

  void swap(String src, String target) {
    if (src == target) {
      return;
    }

    var srcIndex = datas.indexOf(src);
    var targetIndex = datas.indexOf(target);

    print("src = $src , target = $target");

    datas[targetIndex] = src;
    datas[srcIndex] = target;
    setState(() {});

    print("should datas = $datas");
  }
}

print(msg) {}
